from __future__ import annotations

"""
审计日志路由（audit）
--------------------
职责：
- 管理员查询审计日志，支持时间范围、脚本目标、用户、状态过滤
- 支持 JSON 与 CSV 两种返回格式
"""

from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query, Response
from sqlalchemy import and_, select
from sqlalchemy.ext.asyncio import AsyncSession

from ..db import get_session
from ..deps import require_admin
from ..models import AuditLog
from ..schemas import AuditLogItem, AuditResponse
from ..services.utils import export_csv

router = APIRouter(prefix="/admin", tags=["audit"])


@router.get("/audit", response_model=AuditResponse)
async def audit_logs(
    admin=Depends(require_admin),
    session: AsyncSession = Depends(get_session),
    start: str | None = Query(None, alias="from"),
    end: str | None = Query(None, alias="to"),
    script: str | None = Query(None),
    user: str | None = Query(None),
    status: str | None = Query(None),
    limit: int = Query(100, le=1000),
    format: str = Query("json"),
) -> AuditResponse | Response:
    conditions = []
    if start:
        try:
            start_dt = datetime.fromisoformat(start)
        except ValueError as exc:
            raise HTTPException(status_code=400, detail="Invalid from parameter") from exc
        conditions.append(AuditLog.created_at >= start_dt)
    if end:
        try:
            end_dt = datetime.fromisoformat(end)
        except ValueError as exc:
            raise HTTPException(status_code=400, detail="Invalid to parameter") from exc
        conditions.append(AuditLog.created_at <= end_dt)
    if script:
        conditions.append(AuditLog.target == script)
    if user:
        conditions.append(AuditLog.actor_id == int(user))
    if status:
        conditions.append(AuditLog.action == status)

    stmt = select(AuditLog).order_by(AuditLog.created_at.desc()).limit(limit)
    if conditions:
        stmt = stmt.where(and_(*conditions))
    result = await session.execute(stmt)
    entries = result.scalars().all()
    items = [
        AuditLogItem(
            id=entry.id,
            actor_id=entry.actor_id,
            action=entry.action,
            target=entry.target,
            payload_json=entry.payload_json,
            created_at=entry.created_at,
        )
        for entry in entries
    ]

    if format == "csv":
        csv_content = export_csv(
            {
                "id": item.id,
                "actor_id": item.actor_id,
                "action": item.action,
                "target": item.target,
                "created_at": item.created_at.isoformat(),
            }
            for item in items
        )
        return Response(
            content=csv_content,
            media_type="text/csv",
            headers={"Content-Disposition": "attachment; filename=audit.csv"},
        )

    return AuditResponse(items=items, total=len(items))
